package com.creditease.mobile.rss.servicew;

import android.content.Context;
import android.util.Log;
import android.util.Xml;
import com.creditease.mobile.rss.RssConst;
import com.creditease.mobile.rss.dao.RssDB;
import com.creditease.mobile.rss.dao.RssItemDB;
import com.creditease.mobile.rss.model.RssItemModel;
import com.creditease.mobile.rss.model.RssModel;
import com.creditease.mobile.util.FileUtil;
import com.creditease.mobile.util.HttpUtils;
import com.creditease.mobile.util.PicDownloadUtil;
import de.nava.informa.core.ChannelIF;
import de.nava.informa.core.ItemIF;
import de.nava.informa.core.ParseException;
import de.nava.informa.impl.basic.ChannelBuilder;
import de.nava.informa.parsers.FeedParser;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlSerializer;

import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class FeedServices {

    private RssItemDB itemdb;
    private RssDB db;
    private String TAG = FeedServices.class.getName();
    private static final String ROOT = RssConst.APPROOT;

    public FeedServices(Context context) {
        itemdb = new RssItemDB(context);
        db = new RssDB(context);
    }

    /**
     * 刷新Rss内容，并保存到数据库 description
     *
     * @param id
     * @throws Exception
     */
    public RssModel refrush(String id) throws Exception {
        String url = null;
        try {
            RssModel model = db.findById(id);
            url = model.url;
            if (url == null || "".equals(url)) {
                return null;
            }
            Log.d(TAG, "header=================");
            HttpResponse headers = HttpUtils.getHttpHead(url);
            Header header = headers.getFirstHeader("Last-Modified");
            Log.d(TAG, "header=" + header);

            if (model.pubDate != null && header != null) {
                Date lastUpDate = new Date(Long.valueOf(model.pubDate));
                String value = header.getValue();
                if (value != null && !"".equals(value)) {
                    Date lastModified = new Date(value.trim());
                    // 修改时间 更新时间 当且仅当此 Date 对象表示的瞬间比 when 表示的瞬间早，才返回 true；否则返回
                    // false。
                    boolean b = lastModified.before(lastUpDate);
                    if (b) {
                        long count = itemdb.countBySectionId(id);
                        if (count > 0) {
                            return null;
                        }
                    }
                }
            }
            String coder = model.enCode;
            if (coder == null || "null".equals(coder)) {
                coder = "UTF-8";
            }
            Log.d(TAG, "coder=" + coder);

            InputStream is = HttpUtils.getHttpStream(url);

            if (is != null) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(
                        is, coder));
                ChannelIF channel = FeedParser.parse(new ChannelBuilder(), reader);
                List<RssItemModel> items = itemdb.findBySectionId(id);
                Set<String> urlSet = new HashSet<String>();
                for (RssItemModel rss : items) {
                    urlSet.add(rss.articleLink);
                }

                Set<ItemIF> list = channel.getItems();
                int index = 0;
                for (ItemIF b : list) {
                    String link = b.getLink() == null ? "" : b.getLink().toString();
                    // 如果数据库已经保存该文章，则跳过，不保存
                    if (urlSet.contains(link)) {
                        continue;
                    }
                    // 只有第一次触发
                    if (index == 0) {
                        model.desc = b.getTitle().trim();
                        model.isRead = false;
                        model.pubDate = new Date().getTime() + "";
                        model.isSub = true;
                        db.updateById(model);
                    }
                    index++;
                    RssItemModel item = new RssItemModel();
                    item.articleAuthorName = b.getCreator();
                    item.articleLink = link;
                    item.articleTitle = b.getTitle().trim();
                    item.content = b.getDescription();
                    item.isRead = false;
                    item.isFav = false;
                    item.time = new Date().getTime();
                    item.articleTime = b.getDate() == null ? item.time : b
                            .getDate().getTime();
                    item.sectionId = id;
                    itemdb.save(item);
                    downloadImgs(b.getDescription());
                }
                return model;
            }
            throw new Exception("url :" + url + " valid");
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("url :" + url + " valid");
        }
    }

    /**
     * 根据url地址 添加Rss description
     *
     * @param url
     * @throws ParseException
     * @throws Exception
     */

    public void saveRss(RssDB db, String url) throws ParseException, Exception {

        RssModel model = new RssModel();
        try {
            String coder = getEnCode(url);
            Log.d(TAG, "coder=" + coder);

            InputStream is = HttpUtils.getHttpStream(url);
            if (is != null) {
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(is, coder));
                ChannelIF channel = FeedParser.parse(new ChannelBuilder(),
                        reader);
                model.title = channel.getTitle();
                model.url = url;
                model.desc = channel.getDescription();
                model.enCode = coder;
                model.isSub = true;
                model.pubDate = channel.getPubDate() == null ? "" : channel
                        .getPubDate().toString(); // model.logoUrl
                // channel.getImage().getLink().toString();

                long id = db.save(model);
                Set<ItemIF> items = channel.getItems();
                int index = 0;
                for (ItemIF b : items) {
                    // 只有第一次触发
                    if (index == 0) {
                        model.desc = b.getTitle().trim();
                        model.isRead = false;

                        model.pubDate = new Date().toString();
                        db.updateById(model);
                    }
                    index++;
                    String link = b.getLink() == null ? "" : b.getLink()
                            .toString();
                    RssItemModel item = new RssItemModel();
                    item.articleAuthorName = b.getCreator();
                    item.articleLink = link;
                    item.articleTitle = b.getTitle().trim();
                    item.content = b.getDescription();
                    item.isRead = false;
                    item.isFav = false;
                    item.time = new Date().getTime();
                    item.articleTime = b.getDate() == null ? item.time : b
                            .getDate().getTime();
                    item.sectionId = id + "";
                    itemdb.save(item);
                    downloadImgs(b.getDescription());
                }
                reader.close();
                is.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } catch (ParseException e) {
            e.printStackTrace();
            throw new ParseException();
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    private void downloadImgs(String html) {

        if (html == null || "".equals(html.trim())) {
            return;
        }
        Document document = Jsoup.parse(html);
        Elements imgs = document.select("img[src]");
        // String path=RssConst.FILE_PREFIX+RssConst.PIC_TMP_DIR;
        for (Element ele : imgs) {
            String imgurl = ele.attr("src");
            String newFileName = FileUtil.getFileName(imgurl);
            // 后缀
            // ele.attr("src", path+newFileName);
            PicDownloadUtil.add2Queue(imgurl, RssConst.RSS_IMG_CACHE
                    + newFileName);
        }
    }

    /**
     * 备份Rss description
     *
     * @return
     * @throws IOException
     */
    public boolean backupRss() throws IOException {

        List<RssModel> list = db.findAll(true);

        File file = new File(ROOT + File.separator + "RSS.XML");
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        OutputStream fos = new FileOutputStream(file);
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        /* StringBuilder builder = new StringBuilder();
        for (RssModel model : list) {

            builder.append(model.url).append(",").append(model.title)
                    .append(",").append(model.logoUrl).append(",")
                    .append(model.enCode).append(",").append(model.desc)
                    .append("\r\n");
        }
        Log.d(TAG, "backup data:");
        Log.d(TAG, builder.toString());
        bos.write(builder.toString().getBytes());*/
        StringWriter sw = new StringWriter();
        String xml = writeXML(list, sw);
        bos.write(xml.getBytes("UTF-8"));

        bos.flush();
        bos.close();
        fos.close();
        return true;
    }

    public String writeXML(List<RssModel> list, Writer writer) {

        XmlSerializer serializer = Xml.newSerializer();

        try {
            serializer.setOutput(writer);
            serializer.startDocument("UTF-8", true);

            //第一个参数为命名空间,如果不使用命名空间,可以设置为null
            serializer.startTag("", "rss");
            for (RssModel rm : list) {
                serializer.startTag("", "item");

                serializer.startTag("", "title");
                serializer.text(rm.title);
                serializer.endTag("", "title");

                serializer.startTag("", "url");
                serializer.text(rm.url);
                serializer.endTag("", "url");

                serializer.startTag("", "enCode");
                serializer.text(rm.enCode);
                serializer.endTag("", "enCode");

                serializer.startTag("", "isSub");
                serializer.text(rm.isSub + "");
                serializer.endTag("", "isSub");

                serializer.endTag("", "item");
            }

            serializer.endTag("", "rss");
            serializer.endDocument();
            return writer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 恢复Rss description
     *
     * @return
     * @throws IOException
     */
    public boolean restoreRss() throws IOException {

        //        Reader fis = new FileReader(ROOT + File.separator + "RSS.XML");
        //        BufferedReader bis = new BufferedReader(fis);
        InputStream is = new FileInputStream(ROOT + File.separator + "RSS.XML");
        List<RssModel> rsList = pullParseXML(is);
        Map map = new HashMap();
        List<RssModel> list = db.findAll(true);
        for (RssModel model : list) {
            map.put(model.url, "");
        }

        for (RssModel model : rsList) {
            String url = model.url;
            if (map.containsKey(url)) {
                continue;
            }
            db.save(model);
        }
        /*String line = "";
        while ((line = bis.readLine()) != null) {
            String[] str = line.split(",");
            String url = str[0];
            if (map.containsKey(url)) {
                continue;
            }
            RssModel model = new RssModel();
            model.url = url;
            model.title = str[1];
            model.logoUrl = str[2] == null ? "" : str[2];
            model.enCode = str[3] == null ? "UTF-8" : str[3];
            if (str.length > 4) {
                model.desc = str[4];
            }
            model.isSub = true;
            db.save(model);
        }*/

        is.close();
        return true;
    }

    public List<RssModel> pullParseXML(InputStream is) {

        List<RssModel> list = null;
        RssModel model = null;

        //构建XmlPullParserFactory
        try {
            XmlPullParserFactory pullParserFactory = XmlPullParserFactory.newInstance();
            //获取XmlPullParser的实例
            XmlPullParser xmlPullParser = pullParserFactory.newPullParser();
            //设置输入流  xml文件
            xmlPullParser.setInput(is, "UTF-8");

            //开始
            int eventType = xmlPullParser.getEventType();

            try {
                while (eventType != XmlPullParser.END_DOCUMENT) {
                    String nodeName = xmlPullParser.getName();
                    switch (eventType) {
                        //文档开始
                        case XmlPullParser.START_DOCUMENT:
                            list = new ArrayList<RssModel>();
                            break;
                        //开始节点
                        case XmlPullParser.START_TAG:
                            //判断如果其实节点为student
                            if ("item".equals(nodeName)) {
                                //实例化student对象
                                model = new RssModel();
                            } else if ("title".equals(nodeName)) {
                                //设置name
                                model.title = xmlPullParser.nextText();
                            } else if ("url".equals(nodeName)) {
                                //设置sex
                                model.url = xmlPullParser.nextText();
                            } else if ("enCode".equals(nodeName)) {
                                //设置age
                                model.enCode = xmlPullParser.nextText();
                            } else if ("isSub".equals(nodeName)) {
                                //设置email
                                model.isSub = new Boolean(xmlPullParser.nextText());
                            }
                            break;
                        //结束节点
                        case XmlPullParser.END_TAG:
                            if ("item".equals(nodeName)) {
                                list.add(model);
                                model = null;
                            }
                            break;
                        default:
                            break;
                    }
                    eventType = xmlPullParser.next();
                }
            } catch (NumberFormatException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        }

        return list;
    }

    private String getEnCode(String url) throws Exception {
        String coder = "UTF-8";

        InputStream is = HttpUtils.getHttpStream(url);
        if (is != null) {
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(is));
            // 第一行 <?xml version="1.0" encoding="gb2312"?><rss version="2.0">
            String tmp = "encoding=\"";
            String line = reader.readLine();
            String rss = line.substring(line.indexOf(tmp) + tmp.length());
            coder = rss.substring(0, rss.indexOf("\""));
            reader.close();
            is.close();

            if (coder != null && coder.equalsIgnoreCase("gb2312")) {
                coder = "GBK";
            }
        }

        return coder;
    }
}
